// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

const fs = require("fs");
const path = require("path");
const glob = require("glob");

const SITE_ROOT = path.resolve(__dirname, "../"); // docusaurus site root
const REPO_ROOT = path.resolve(SITE_ROOT, "../../.."); // monorepo root
const OUT_FILE = path.join(SITE_ROOT, ".generated/ImportContentMap.ts");

// Where to look for MDX that might use <ImportContent>
const MDX_GLOBS = [path.join(REPO_ROOT, "docs/content/**/*.{md,mdx}")];

// Optionally constrain which repo roots are permitted for mode="code"
const ALLOWED_ROOTS = new Set(["crates", "external-crates", "examples"]);

// --- helpers ---
const readText = (p) => fs.readFileSync(p, "utf8").replace(/\r\n?/g, "\n");

function stripFencedCode(md) {
  // remove ``` blocks to avoid matching tags shown in code samples
  return md.replace(/```[\s\S]*?```/g, "");
}

// Finds <ImportContent ...> start tags (self-closing or not), attribute order agnostic
const IMPORT_TAG_RE = /<ImportContent\b[^>]*\/?>(?!\s*<\/ImportContent>)/gi;

function* findCodeSources(mdx) {
  const haystack = stripFencedCode(mdx);
  let m;
  while ((m = IMPORT_TAG_RE.exec(haystack))) {
    const tag = m[0];
    if (!/\bmode\s*=\s*["']code["']/i.test(tag)) continue;
    if (/\borg\s*=\s*/i.test(tag)) continue; // silently skip tags that include an org value
    const srcM = /\bsource\s*=\s*["']([^"']+)["']/i.exec(tag);
    const src = srcM ? srcM[1].trim() : "";
    if (src) yield src;
  }
}

function normalizeRepoRel(src) {
  // strip leading ./ or / for consistency
  return src.replace(/^\/+/, "").replace(/^\.\//, "");
}

// --- main ---
const mdxFiles = MDX_GLOBS.flatMap((g) => glob.sync(g, { nodir: true }));
if (process.env.DEBUG_IMPORT_CONTENT) {
  console.log(`[generate-import-context] Globs:`, MDX_GLOBS);
  console.log(`[generate-import-context] MDX files found: ${mdxFiles.length}`);
}
const wanted = new Set();

for (const mdxPath of mdxFiles) {
  const text = readText(mdxPath);
  for (const raw of findCodeSources(text)) {
    const rel = normalizeRepoRel(raw);
    const [root] = rel.split("/");
    if (!ALLOWED_ROOTS.has(root)) {
      // Skip unknown roots
      console.warn(`[skip] Unsupported root "${root}" in ${mdxPath}: ${rel}`);
      continue;
    }
    wanted.add(rel);
  }
}

const entries = [];
for (const rel of Array.from(wanted).sort()) {
  const abs = path.join(REPO_ROOT, rel);
  if (!fs.existsSync(abs) || !fs.statSync(abs).isFile()) {
    console.warn(`[warn] Missing file for ImportContent: ${rel}`);
    continue;
  }
  const text = readText(abs);
  entries.push(`  ${JSON.stringify(rel)}: ${JSON.stringify(text)}`);
}

const out = `// AUTO-GENERATED. Do not edit.
// Generated by scripts/generate-import-context.js
export const importContentMap = {
${entries.join(",\n")}
};
`;

fs.mkdirSync(path.dirname(OUT_FILE), { recursive: true });
fs.writeFileSync(OUT_FILE, out, "utf8");
console.log(`Wrote ${OUT_FILE} with ${entries.length} entries.`);
